package bsh.utils.reflection.transform;


import org.objectweb.asm.MethodVisitor;

import bsh.CompilationState;
import bsh.Primitive;
import bsh.meta.JavaClassWrapper;
import bsh.meta.TypeTransformation;
import bsh.meta.TypeWrapper;
import bsh.utils.reflection.BytecodeHelper;

/**
 * {@link TypeTransformation} para fazer 'boxing' de primitivas
 * 
 * @author takeshi
 */
public class BoxTypeTransformation implements TypeTransformation {

    /**
     * {@inheritDoc}
     */
    public boolean acceptsType(TypeWrapper type) {
        return type.isPrimitive();
    }

    /**
     * {@inheritDoc}
     */
    public TypeWrapper toType(TypeWrapper fromType) {
        return JavaClassWrapper.wrapperFor(Primitive.boxType(((JavaClassWrapper) fromType).getJavaType()));
    }

    /**
     * {@inheritDoc}
     */
    public TypeWrapper transformStackTop(MethodVisitor visitor, TypeWrapper fromType, CompilationState state) {
        state.assertMinimumStackSize(1);
        Class<?> type = ((JavaClassWrapper) fromType).getJavaType();
        BytecodeHelper.autoBox(visitor, type);
        state.popStack();
        final TypeWrapper target = this.toType(fromType);
        state.pushStack(target);
        return target;
    }

}
